﻿/**
 * Spring
 *
 * @author		Allen Chou
 * @version		1.0.2 (last update: Dec 3 2008)
 * @link        http://cjcat.blogspot.com
 * @link		http://cjcat2266.deviantart.com
 */

package idv.cjcat.physics.fenozix {
	import idv.cjcat.*;
	import idv.cjcat.geom.*;

	/**
	 * A <code>Spring</code> object represents a spring constraint used in the <code>Fenizix</code> physics simulation
	 */
	public class Spring extends AbstractConstraint {
		
		private var _stiffness:Number;
		private var _length:Number;
		
		/**
		 * Creates a spring constraint between two objects.
		 * This class is not meant to be instantiated directly.
		 * Use the <code>Fenozix.createSpring()</code> method to obtain a spring reference.
		 * @param	obj1       The first object data.
		 * @param	obj2       The second object data.
		 * @param	stiffness  The stiffness of the spring. This value should lie between 0 and 1.
		 * @param	length     The length of the spring.
		 */
		
		public function Spring(obj1:ObjectData, obj2:ObjectData, stiffness:Number, length:Number) {
			super(obj1, obj2);
			
			if (isNaN(length)) length = CJGeom.distance(obj1.obj, obj2.obj);
			
			this.stiffness = stiffness;
			this.length = length;
		}
		
		/**
		 * The stiffness of the spring. This value should lie between 0 and 1.
		 */
		public function get stiffness():Number { return _stiffness; }
		public function set stiffness(value:Number):void { _stiffness = CJMath.clamp(value, 0, 1); }
		
		/**
		 * The length of the spring.
		 */
		public function get length():Number { return _length; }
		public function set length(value:Number):void { _length = CJMath.clamp(value, 0, Number.MAX_VALUE); }
		
		/** @private */
		internal override function step(stepInterval:Number):void {
			var dx:Number = CJGeom.distance(obj1.obj, obj2.obj) - length;
			var force:Vector2 = new Vector2(obj2.obj.x - obj1.obj.x, obj2.obj.y - obj1.obj.y);
			
			force.length = stiffness * dx * stepInterval;
			if (obj1.mass != 0) {
				obj1.vx += force.x / obj1.mass;
				obj1.vy += force.y / obj1.mass;
			}
			
			if (obj2.mass != 0) {
				obj2.vx -= force.x / obj2.mass;
				obj2.vy -= force.y / obj2.mass;
			}
		}
	}
}